#Author http://www.cnblogs.com/Jame-mei
from tabulate import tabulate


#4->5
def print_log(msg,log_type="info"):
    if log_type=='info':
        print (msg)
    elif log_type=='error':
        print ("\033[31;1m%s\033[0m"%msg)

#3.
db_file='staff_db'
columns=['id','name','age','phone','dept','enrolled_date']
def load_db(db_file):
    '''
    加载员工信息表，并转换成执行的格式
    :param db_file
    :return:
    '''
    #生成一个空字典
    data={}
    for i in columns:
        data[i]=[]

    with open(db_file,'r',encoding='utf-8') as r_f:
        for line in r_f:
            staff_id,name,age,phone,dept,enrolled_date=line.split(',')
            data['id'].append(staff_id)
            data['name'].append(name)
            data['age'].append(age)
            data['phone'].append(phone)
            data['dept'].append(dept)
            data['enrolled_date'].append(enrolled_date)
    return data

staff_data=load_db(db_file) #程序启动就要生成！




#2->4
def op_gt(column,condtion_val):
    '''
    :param column: age,name,id....
    :param condtion_val: eg.22
    :return:[[id,name,age,phone]...]
    '''
    matched_records=[]
    for index,val in enumerate(staff_data[column]): #'age':[18,21,24...]
        if float(val)>float(condtion_val):
            #print("match",index,val)
            record=[] #小列表存放每一个用户的数据。
            for col in columns: #之前定义的按顺序的列表，格式不会乱。
                record.append(staff_data[col][index])
            matched_records.append(record)
        else:
            continue #没有匹配上，可以循环。
    #print(matched_records)
    return matched_records

def op_lt(column,condtion_val):
    matched_records = []
    for index, val in enumerate(staff_data[column]):  # 'age':[18,21,24...]
        if float(val) < float(condtion_val):
            #print("match", index, val)
            record = []  # 小列表存放每一个用户的数据。
            for col in columns:  # 之前定义的按顺序的列表，格式不会乱。
                record.append(staff_data[col][index])
            matched_records.append(record)
        else:
            continue  # 没有匹配上，继续循环也可以不谢。
    #print(matched_records)
    return matched_records

def op_eq(column,condtion_val):
    matched_records = []
    for index, val in enumerate(staff_data[column]):  # 'age':[18,21,24...]
        if val == condtion_val: #如果是字符串float会报错
            #print("match", index, val)
            record = []  # 小列表存放每一个用户的数据。
            for col in columns:  # 之前定义的按顺序的列表，格式不会乱。
                record.append(staff_data[col][index])
            matched_records.append(record)
        else:
            continue  # 没有匹配上，继续循环也可以不谢。
    #print(matched_records)
    return matched_records

def op_like(column,condtion_val):
    matched_records = []
    for index, val in enumerate(staff_data[column]):  # 'age':[18,21,24...]
        if condtion_val in val:  # like条件包含在val大列表里面。
            #print("match", index, val)
            record = []  # 小列表存放每一个用户的数据。
            for col in columns:  # 之前定义的按顺序的列表，格式不会乱。
                record.append(staff_data[col][index])
            matched_records.append(record)
        else:
            continue  # 没有匹配上，继续循环也可以不谢。
    #print(matched_records)
    return matched_records


def syntax_where(clause):
    '''
    解析where 条件，并过滤数据
    :param clause:  eg.age>22
    :return:
    '''
    operators={
        '>':op_gt,
        '<':op_lt,
        '=':op_eq,
        'like':op_like
    }
    for op_key,op_func in operators.items():
        if op_key in clause:
            column,val=clause.split(op_key)
            #print (column,val)
            matched_data=op_func(column.strip(),val.strip()) #将过滤的条件传进具体的><= like的进行进一步执行操作！
            return  matched_data #返回传回syntax_parser()函数！！

    else:#只有在for在执行完成，没有被break情况下才执行==没匹配上任何的条件公式！！
        print_log('语法错误:where 条件只支持[>,<,=,like]','error')




#4->>5 增删改查的前半部分条件，过滤指定的列来进行显示
def syntax_find(data_set,query_clause):
    '''
    解析查询语句按字段过滤的条件，例如name,age要显示指定的列
    :param data_set: [['24', 'alex', '18', '13120378203', '运维', '2013-3-1\n']]
    :param query_clause: eg.find name,age from staff_table
    :return:
    '''

    filter_cols_tmp=query_clause.split('from')[0][4:].split(',')  #老师的方法，过滤出来name,age有空格的。
    #print (filter_cols_tmp)
    filter_cols=[i.strip() for i in filter_cols_tmp] #干净的column


    #最终匹配到的数据
    reformat_data_set=[]
    #根据查询的字段找到对应的索引
    for row in data_set:
        filtered_vals=[] #把要打印的字段放在这个列表里
        for col in filter_cols:
            col_index=columns.index(col) #拿到索引,依次取出每条记录对应索引的值！
            #print(col,row[col_index])
            filtered_vals.append(row[col_index])
        reformat_data_set.append(filtered_vals)

    # for r in reformat_data_set:
    #     print (r)
    #让打印出来的格式更加友好
    print(tabulate(reformat_data_set,headers=filter_cols,tablefmt='grid'))

def syntax_delete(data_set,query_clause):
    pass

def syntax_update(data_set,query_clause):
    '''
    :param data_set:[['24', 'alex', '18', '13120378203', '运维', '2013-3-1\n']]
    :param query_clause: eg.update staff_table set age=25
    :return:
    '''
    formula_raw=query_clause.split('set')
    if formula_raw>1: #有set关键字
        pass
    else:
        print_log('语法错误，未检测到set关键字!','error')

def syntax_add(data_set,query_clause):
    pass




#2
syntax_list={
    'find':syntax_find,
    'del':syntax_delete,
    'update':syntax_update,
    'add':syntax_add,
}
def syntax_parser(cmd):
    '''
    解析sql语句并分发给指定的增删改查取执行，要先判断语法的合法性。
    :param cmd:
    :return:
    '''
    if cmd.split()[0] in ('find','add','del','update'):
        #开始解析sql语句
        query_clause,where_clause=cmd.split('where')
        print (query_clause,where_clause) #打印您输入的语句，where切分后的结果！
        matched_records=syntax_where(where_clause)

        cmd_action=query_clause.split()[0] #cmd_action是finde/add/del/update等动作
        if cmd_action in syntax_list:
            syntax_list[cmd_action](matched_records,query_clause) #传入个find/delete/update/add等具体函数作为参数！
            #matched_records为where后面的条件语句,query_clause为where前面的语句，传入给具体的增删改查的函数。

    else:
        print_log (r'语法错误:[find\add\del\update] [column1,...] from [staff_table] [where] [column1...][>,<,=...][condtion]','error')





#1
def main():
    '''
    让用户输入sql语句，并执行
    :return:
    '''
    while True:
        cmd=input('[staff_db]:').strip()
        if not cmd:continue
        syntax_parser(cmd.strip()) #去掉find/update/add/del整条语句收尾空格！


if __name__ == '__main__':
    main()